package com.spring.controller.javastack.request;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.util.HashSet;
import java.util.Set;

/**
 * Spring中获取Request的几种方法及其线程安全性分析
 *
 * Created by chenhs on 2018/6/12.
 *
 * 分析：
 *     在Spring中，Controller的scope是singleton(单例)，也就是说在整个web系统中，只有一个TestController；但是其中注入的request却是线程安全的，
 * 原因在于：使用这种方式，当Bean（本例的TestController）初始化时，Spring并没有注入一个request对象，而是注入了一个代理（proxy）；当Bean中需要
 * 使用request对象时，通过该代理获取request对象。
 */
@Controller
public class Fetch2Controller {

    @Autowired
    private HttpServletRequest request;

    //存储已有参数，用于判断是否重复，从而判断线程是否安全
    public static Set<String> set = new HashSet<>();

    @RequestMapping("/test2")
    public void test() throws InterruptedException {

        String value = request.getParameter("key");

        if (set.contains(value)) {
            System.out.println(value + "\t重复出现，request并发不安全！");
        } else {
            System.out.println(value);
            set.add(value);
        }

        //模拟线程执行了一段时间
        Thread.sleep(1000);
    }

}
